//
//  TMValue.swift
//  ThemeManagement
//
//  Created by fanxiaoxin_1987@126.com on 06/20/2022.
//  Copyright (c) 2022 fanxiaoxin_1987@126.com. All rights reserved.
//

import UIKit

/// 代表每个可变更的值，如UIColor, UIImage等
@dynamicCallable
public struct TMValue<Value> {
    /// 存储了所有样式对应的值，若没有指定值则取default的
    let values: [TMTheme: () -> Value]
    public init(_ values: [TMTheme: () -> Value]) {
        self.values = values
    }
    public init(_ values: [TMTheme: Value]) {
        self.values = values.mapValues({ v in { v } })
    }
    public func value(for theme: TMTheme) -> Value? {
        return self.values[theme]?() ?? self.values[.default]?()
    }
    // 替换其中的某些值
    public func replace(_ values: [TMTheme: () -> Value]) -> Self {
        var newValues = self.values
        values.forEach { newValues[$0.key] = $0.value }
        return .init(newValues)
    }
    // 替换其中的某些值
    public func replace(_ values: [TMTheme: Value]) -> Self {
        var newValues = self.values
        values.forEach { kv in newValues[kv.key] = { kv.value } }
        return .init(newValues)
    }
    // 替换其中的某些值
    public func dynamicallyCall(withKeywordArguments pairs: KeyValuePairs<String, () -> Value>) -> Self {
        var values = self.values
        pairs.forEach { values[.init(rawValue: $0.key)] = $0.value }
        return .init(values)
    }
    // 替换其中的某些值
    public func dynamicallyCall(withKeywordArguments pairs: KeyValuePairs<String, Value>) -> Self {
        var values = self.values
        pairs.forEach { kv in values[.init(rawValue: kv.key)] = { kv.value } }
        return .init(values)
    }
    public static func empty() -> Self {
        let empty: [TMTheme: () -> Value] = [:]
        return .init(empty)
    }
}

extension TMValue: ExpressibleByDictionaryLiteral where Value == UIColor {
    public init(dictionaryLiteral elements: (TMTheme, UInt32)...) {
        var values: [TMTheme: () -> Value] = [:]
        for element in elements {
            values[element.0] = {
                if element.1 > 0xFFFFFF {
                    return .init(red: CGFloat((element.1 & 0xFF000000) >> 24) / 255.0,
                                green:CGFloat((element.1 & 0xFF0000) >> 16) / 255.0,
                                blue:CGFloat((element.1 & 0xFF00) >> 8) / 255.0,
                                alpha:CGFloat(element.1 & 0xFF) / 255.0)
                } else {
                    return .init(red: CGFloat((element.1 & 0xFF0000) >> 16) / 255.0,
                                        green:CGFloat((element.1 & 0xFF00) >> 8) / 255.0,
                                        blue:CGFloat(element.1 & 0xFF) / 255.0,
                                        alpha:1)
                }
            }
        }
        self.values = values
    }
}

extension TMValue where Value == UIImage {
    /// 同一张图片根据不同的主题染色
    public static func tint(_ image: UIImage?, color: TMValue<UIColor>) -> Self {
        if let image = image {
            return .init(color.values.mapValues({ color in
                return {
                    UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
                    let rect = CGRect(origin: .zero, size: image.size)
                    color().set()
                    UIRectFill(rect)
                    image.draw(at: .zero, blendMode: .destinationIn, alpha: 1)
                    let newImage = UIGraphicsGetImageFromCurrentImageContext()
                    UIGraphicsEndImageContext()
                    return newImage ?? image
                }
            }))
        } else {
            return .empty()
        }
    }
    /// 同一张图片根据不同的主题染色
    public static func tint(_ imageName: String, color: TMValue<UIColor>) -> Self {
        return .tint(.init(named: imageName), color: color)
    }
}
